<?php
$libdir = dirname(__FILE__);
require_once "{$libdir}/coreLib.php";

class Element extends lib
{
	private $tag = 'div'; // the default tag is <div>
	private $childs = array();	//the descendents
	private $text;	// the string content of the element
	private $attributes = array();	//tag attributes

        public static $nrElements = 0;
        private $UID;
	public function __construct()
	{
            self::$nrElements ++;
            $this->UID = 'Element'.self::$nrElements;
	}
	
	public function __clone()
	{
            //OMG! I'm gettin cloned
            self::$nrElements ++;
            $this->UID.=self::$nrElements;
	}

        /**
         * Get the element's ID
         */
        public function getID()
        {
            return $this->UID;
        }
	/**
	*	Get the name of the tag
	*/
	public function getTag()
	{
		return $this->tag;
	}
	
	/**
	*	Set a new tag type
	*	@param string $newname the new tag name
	*/
	public function setTag($newname)
	{
		$newname = trim($newname);
		if(preg_match("/^[a-z][a-z1-6]*$/i",$newname))
			$this->tag = $newname;
		//error
	}
	
	/**
	*	Get a attribute value
	*	@param string $attrName the index of the atribute
	*/
	public function getAttribute($attrName)
	{
		return $this->attributes[$attrName];
	}
	
	/**
	*	Set an attribute value
	*	@param string $attrName the index of the attribute
	*	@param string $attrValue the new value for the attribute
	*/
	public function setAttribute($attrName, $attrValue)
	{
		$attrName = trim($attrName);
		if(preg_match("/^[a-z]*$/i",$attrName))
			$this->attributes[$attrName] = "{$attrValue}";
	}
	/**
	* Set the inner text of the element. This can contain simple HTML code too
	* @param string $newText the new inner text
	*/
	public function setText($newText)
	{
		$this->text = $newText;
	}
	/**
	* Get the current inner textdomain
	*/
	public function getText()
	{
		return $text;
	}
	
	/**
	* addChild - add a child node to the element
	* @param Element $child the Element to be added
	* @param bool $before when displayed, is it before the text?
	* @param int $position the position in the children array. -1 to add it to the end of the array
	* 
	*/
	public function addChild(Element $child, $before = true, $position = -1)
	{
		if($child instanceof Element)
		{
			$toAdd = array(
				'element'=>$child,
				'before'=>$before	//before internal text?
				);
			$nrChilds = count($this->childs);
			if($position == -1 || $position >= $nrChilds)
			{
				//the inserted position is the end of the array
				$position = $nrChilds;
			}else
			{
				//we need to make room for the new Element
				for($i = $nrChilds; $i > $position; $i--)
				{
					$this->childs[$i] = $this->childs[$i-1];
				}
			}
			$this->childs[$position] = $toAdd;
		}
		
	}
	

	/**
	*	Display or fetch the Element's HTML code
	*	@param bool $echo Display and fetch(true) or just fetch(false)
	*/
	public function toHtml($echo = true)
	{
		/* Register child elements */
		$htmlBefore = "";
		$htmlAfter = "";
		$nrChilds = count($this->childs);
		for($i=0; $i < $nrChilds; $i++)
		{
			if($this->childs[$i]['before'])
			{
				$htmlBefore.=$this->childs[$i]['element']->toHtml(false);
				$htmlBefore.="\n";
			}else
			{
				$htmlAfter.=$this->childs[$i]['element']->toHtml(false);
				$htmlAfter.="\n";
			}
		}
		/*Register start-tag attributes*/
		$tag = $this->tag;
		foreach($this->attributes as $attr=>$value)
		{
			$tag.=" $attr=\"".$value."\"";
		}
		
		/* Echo if necessary */
		if($echo)
		{
			echo "<{$tag}>".$htmlBefore,$this->text,$htmlAfter."</{$this->tag}>";
		}
		return "<{$tag}>".$htmlBefore.$this->text.$htmlAfter."</{$this->tag}>";
	}

    public function  __toString() {
        return $this->toHtml(false);
    }
}
